package hu.ikti.oamadmin.beans.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import hu.ikti.oamadmin.beans.BaseBean;
import hu.ikti.oamadmin.types.entities.Bundle;
import hu.ikti.oamadmin.types.entities.ByteCode;
import hu.ikti.oamadmin.types.entities.Repository;
import hu.ikti.oamadmin.types.entities.Resource;
import hu.ikti.oamadmin.types.entities.Service;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.international.StatusMessage.Severity;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

@Name("editServiceBean")
@Scope(ScopeType.CONVERSATION)
public class EditServiceBean extends BaseBean implements Serializable {

	private static final long serialVersionUID = 1L;

	@In(create = true)
	@Out
	private Service service;

	@In(required = false)
	private List<Service> serviceList;

	@In(required = false, value = "selectedRepository")
	@Out(required = false, value = "selectedRepository")
	private Repository repository;

	@Out(required = false, value = "serviceBundles")
	private List<Bundle> bundleList;

	@Out(required = false, value = "selectedBundles")
	private List<Bundle> selectedBundles;

	private void updateServiceBundles() {
		List<?> results = entityManager
				.createQuery(
						"select bundle from Bundle bundle "
								+ "left outer join bundle.bundleData as bundleData "
								+ "left outer join bundleData.repository as repository "
								+ "where bundle.bundleData.deleted = false "
								+ "and repository = :repo "
								+ "and bundle.service = null "
								+ "and bundle.serviceProfile = null "
								+ "and bundle.gateway = null "
								+ "order by bundle.bundleData.symbolicName")
				.setParameter("repo", repository).getResultList();
		if (results != null) {
			bundleList = new ArrayList<Bundle>();
			for (Object object : results) {
				bundleList.add((Bundle) object);
			}
		}
	}

	public String toEditBundles() {
		updateServiceBundles();
		return "next";
	}

	public String toEditResources() {
		if (service.getId() != null) {
			service = (Service) entityManager
					.createQuery(
							"select service from Service service "
									+ "left outer join service.resources "
									+ "where service.id = :id")
					.setParameter(0, service.getId()).getSingleResult();
		}
		return "toEditResources";
	}

	public void cancel() {
		FacesMessages.instance().add(Severity.WARN, "Transaction canceled!");
	}

	@Begin(pageflow = "editService", join = true)
	public String newService() {
		return "start";
	}

	@Begin(pageflow = "editService", join = true)
	public String editService() {
		try {
			service = (Service) entityManager.find(Service.class,
					service.getId());
			repository = service.getRepository();

			List<Bundle> oldBundles = service.getBundles();

			updateServiceBundles();

			for (Bundle bundle : bundleList) {
				for (Bundle oldBundle : oldBundles) {
					if (bundle.getBundleData()
							.equals(oldBundle.getBundleData())) {
						bundle.setSelected(true);
					}
				}
			}

			return "editBundles";
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public String saveService() {
		try {
			if (service.getId() != null) {
				service = (Service) entityManager.find(Service.class,
						service.getId());
			} else {
				entityManager.persist(service);
			}

			service.setRepository(repository);

			List<Bundle> oldBundles = service.getBundles();
			for (Bundle bundle : oldBundles) {
				bundle = (Bundle) entityManager.find(Bundle.class,
						bundle.getId());
				entityManager.remove(bundle);
			}
			service.getBundles().clear();

			for (Bundle bundle : bundleList) {
				if (bundle.isSelected()) {
					Bundle cloneBundle = new Bundle();
					cloneBundle.setBundleData(bundle.getBundleData());
					cloneBundle.setService(service);
					cloneBundle.setParent(bundle);
					entityManager.persist(cloneBundle);
					service.getBundles().add(cloneBundle);
				}
			}

			service = entityManager.merge(service);

			if (!serviceList.contains(service)) {
				serviceList.add(service);
			}

			FacesMessages.instance().add(Severity.INFO, "Saved: #0 #1",
					service.getName(), service.getDescription());

			return "done";
		} catch (Exception e) {
			e.printStackTrace();
			FacesMessages.instance().add(Severity.ERROR, "System error!");
			return null;
		}
	}

	public void uploadListener(UploadEvent event) throws Exception {
		UploadItem item = event.getUploadItem();
		String[] parsedFileName = item.getFileName().split("\\.");
		Resource resource = new Resource();
		ByteCode byteCode = new ByteCode();
		byteCode.setBytes(item.getData());
		resource.setByteCode(byteCode);
		resource.setExtension(parsedFileName[parsedFileName.length - 1]);
		resource.setFileName(item.getFileName());
		resource.setUploadTime(Calendar.getInstance().getTime());
		resource.setSize(item.getFileSize());
		service.getResources().add(resource);
	}

	public String toSummary() {
		selectedBundles = new ArrayList<Bundle>();
		for (Bundle bundle : bundleList) {
			if (bundle.isSelected()) {
				selectedBundles.add(bundle);
			}
		}
		return "toSummary";
	}

}
